package safeCommitter.test.executor.junit;

import java.util.Set;

import org.junit.runner.JUnitCore;
import org.junit.runner.Request;
import org.junit.runner.Result;

import safeCommitter.model.TestType;
import safeCommitter.test.executor.common.TestResultType;
import safeCommitter.test.executor.launcher.socket.SCTestSocketWriter;
import safeCommitter.test.report.SCReport;

public class JunitExecutor {

	private static final String SEPARATOR = "~";

	public SCReport execJunit(final Set<Request> junitTestSuite,
			final SCTestSocketWriter socketWriter) {
		JUnitCore core = new JUnitCore();
		Integer testCount = 0;
		Boolean passed = Boolean.TRUE;
		SCReport report = new SCReport();
		for (Request r : junitTestSuite) {
			Result result = core.run(r);
			String resultString = getResultString(r, result);
			testCount += r.getRunner().testCount();
			passed = passed && result.wasSuccessful();
			socketWriter.write(resultString);
			report.addDescription(resultString);
		}
		report.setTestCount(testCount);
		report.setTestsPassed(passed);
		return report;

	}

	private String getResultString(final Request r, final Result result) {
		TestResultType type = getType(result);
		StringBuilder sb = new StringBuilder();
		sb.append(TestType.JUNIT.name()).append(SEPARATOR);
		sb.append(type.name()).append(SEPARATOR);
		String[] split = r.getRunner().getDescription().getChildren().get(0)
				.getDisplayName().split("\\(");
		String methodName = split[0];
		String clazzName = split[1].replace(")", ".");
		sb.append(clazzName).append(methodName).append(SEPARATOR);
		sb.append(result.getRunTime());
		return sb.toString();

	}

	private TestResultType getType(final Result result) {
		return result.wasSuccessful() ? TestResultType.SUCCESS
				: TestResultType.FAILING;
	}
}
